package com.zzgele.qmzb.api.utils;

import com.zzgele.qmzb.api.core.Constants;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;

/**
 * AES加密解密算法
 */
public class AesEncryptionUtil {
	/** 算法/模式/填充 **/
	private static final String CipherMode = "AES/CBC/PKCS5Padding";
	private static final String AES_KEY = Constants.IM_AES_KEY;
	private static final String AES_IV = Constants.IM_AES_IV;

	/** 创建密钥 **/
	private static SecretKeySpec createKey(String key) {
		byte[] data = null;
		if (key == null) {
			key = "";
		}
		StringBuffer sb = new StringBuffer(16);
		sb.append(key);
		while (sb.length() < 16) {
			sb.append("0");
		}
		if (sb.length() > 16) {
			sb.setLength(16);
		}

		try {
			data = sb.toString().getBytes("UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return new SecretKeySpec(data, "AES");
	}

	private static IvParameterSpec createIV(String iv) {
		byte[] data = null;
		if (iv == null) {
			iv = "";
		}
		StringBuffer sb = new StringBuffer(16);
		sb.append(iv);
		while (sb.length() < 16) {
			sb.append("0");
		}
		if (sb.length() > 16) {
			sb.setLength(16);
		}

		try {
			data = sb.toString().getBytes("UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return new IvParameterSpec(data);
	}

	/** 加密字节数据 **/
	private static byte[] encrypt(byte[] content, String key, String iv) {
		try {
			SecretKeySpec secretKeySpec = createKey(key);
			Cipher cipher = Cipher.getInstance(CipherMode);
			cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, createIV(iv));
			byte[] result = cipher.doFinal(content);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/** 加密字符串数据 **/
	public static String encrypt(String content, String key, String iv) {
		//过滤空格和换行
		content = content.replace(" ", "").replace("\n", "");

		byte[] data = null;
		try {
			data = content.getBytes("UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		}
		data = encrypt(data, key, iv);
		//String result = byte2hex(data); //16进制方式
		//String result = new sun.misc.BASE64Encoder().encode(data); //base64方法1
		String result = new Base64().encodeBase64String(data); //base64方法2
		return result;
	}

	/** 解密字节数组 **/
	private static byte[] decrypt(byte[] content, String key, String iv) {
		try {
			SecretKeySpec secretKeySpec = createKey(key);
			Cipher cipher = Cipher.getInstance(CipherMode);
			cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, createIV(iv));
			byte[] bytes = cipher.doFinal(content);
			return bytes;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/** 解密(输出结果为字符串) **/
	public static String decrypt(String content, String key, String iv) {
		byte[] data = null;
		try {
			//data = hex2byte(content); //16进制方式
			//data = new sun.misc.BASE64Decoder().decodeBuffer(content); //base64方法1

			data = content.getBytes("UTF-8"); //base64方法2
			data = Base64.decodeBase64(data);
		} catch (Exception e) {
			e.printStackTrace();
		}
		data = decrypt(data, key, iv);

		String result = null;
		if (data != null) {
			try {
				result = new String(data, "UTF-8");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		return result;
	}

	/** 字节数组转成16进制字符串 **/
	public static String byte2hex(byte[] b) { // 一个字节的数，
		StringBuffer sb = new StringBuffer(b.length * 2);
		String tmp = "";
		for (int n = 0; n < b.length; n++) {
			// 整数转成十六进制表示
			tmp = (Integer.toHexString(b[n] & 0XFF));
			if (tmp.length() == 1) {
				sb.append("0");
			}
			sb.append(tmp);
		}
		return sb.toString().toUpperCase(); // 转成大写
	}

	/** 将hex字符串转换成字节数组 **/
	private static byte[] hex2byte(String inputString) {
		if (inputString == null || inputString.length() < 2) {
			return new byte[0];
		}
		inputString = inputString.toLowerCase();
		int l = inputString.length() / 2;
		byte[] result = new byte[l];
		for (int i = 0; i < l; ++i) {
			String tmp = inputString.substring(2 * i, 2 * i + 2);
			result[i] = (byte) (Integer.parseInt(tmp, 16) & 0xFF);
		}
		return result;
	}

	public static void main(String ages[]) {
		String str = "{\n"
				+ "  \"user_info\" : {\n"
				+ "    \"age\" : 0,\n"
				+ "    \"live_status\" : \"0\",\n"
				+ "    \"ticket\" : 0,\n"
				+ "    \"user_id\" : 56,\n"
				+ "    \"city_id\" : 130200,\n"
				+ "    \"level\" : 0,\n"
				+ "    \"number\" : 10100564,\n"
				+ "    \"height\" : 0,\n"
				+ "    \"spend\" : 0,\n"
				+ "    \"city\" : \"唐山市\",\n"
				+ "    \"fans\" : 0,\n"
				+ "    \"attention\" : 0,\n"
				+ "    \"province_id\" : 130000,\n"
				+ "    \"authentication_status\" : 0\n"
				+ "  }\n"
				+ "}";
		System.out.println("加密 - " + str);
		System.out.println("加密后 - " + encrypt(str));
		System.out.println("再解密 - " + decrypt(encrypt(str)));

		//解密测试
		String strEncrypted = "34zGoG24ckXmfM0xYrpNo3Xp5ZIVdgvun03BzbTJTxtVpDKKtmTYnsjHBmYzIKtI"
				+ "Dt4DjAR4der/5hCJy7qNqNNS9GvgqxS/JAryKg0TLhMOJQlAgZxcs9wI39wESJD2"
				+ "1tCuu9u7bqX78ifJooW5etuu6p7sstaaxUW0ilpxDYJMrKiciAxKH012iJjzgk2K"
				+ "WlXJikvsoYAkOWqyvUUJOF0YkQVKXCa53Y+wWpYnLtRMU8hDZdDFn5EgNPHkDKwV"
				+ "o1rCsbertjV/1upaZbamfmGYFuDz0bIEuq5uhBJqYbcIz8sJqe4y/4jbjzU8ReMW"
				+ "K1PrX5Kk43ymKWt+p9YYOVg4MhBApBbHl0W/FCIqKFjrUJcH43M0jadFbt1zUblb"
				+ "nak2ug44MLiGM+wmTlaU3+LK12BYcVyD4YRxUZr9sxPBSf/OqpAhhDB4hr3d8M0J";
		System.out.println("解密 - " + strEncrypted);
		System.out.println("解密后 - " + decrypt(strEncrypted));
		System.out.println("再加密 - " + encrypt(decrypt(strEncrypted)));
	}

	public static String encrypt(String str) {
		return encrypt(str, AES_KEY, AES_IV);
	}

	public static String decrypt(String str) {
		return decrypt(str, AES_KEY, AES_IV);
	}
}